package com.borya.service.mobile.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.borya.constant.RedisConstant;
import com.borya.dao.*;
import com.borya.filter.auth.AppSignTokenVersion;
import com.borya.framework.annotation.Autowired;
import com.borya.framework.annotation.Component;
import com.borya.framework.util.ObjectUtils;
import com.borya.model.db.*;
import com.borya.model.entity.*;
import com.borya.model.enumcation.OtherConfType;
import com.borya.service.impl.BaseServiceImpl;
import com.borya.service.mobile.UserService;
import com.borya.statuscode.StatusCode;
import com.borya.task.AutomaticAudittask;
import com.borya.task.model.RespInfo;
import com.borya.util.*;
import com.borya.util.AliOSSUtil.UploadResult;
import com.borya.util.Constant.SourceType;
import com.borya.util.cipher.EncryptUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;

import java.awt.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.time.Clock;
import java.util.List;
import java.util.*;

@Component("userServiceImpl")
public class UserServiceImpl extends BaseServiceImpl implements UserService {

	public Logger log = Logger.getLogger(getClass());

	private static final Map<String, SmsInfo> SMC_CODE_MAP = new HashMap<>();
	private static final long SMS_TIMEOUT = Constant.SMS_TIMEOUT;

	@Autowired("userDAOImpl")
	private UserDAO userDAO;

	@Autowired("messageDAO")
	private MessageDAO messageDAO;

	@Autowired("webUserDAOImpl")
	private WebUserDAO webUserDAO;
	@Autowired("merchantDAO")
	private MerchantDAO merchantDAO;

	@Autowired("appConfDAOImpl")
	private AppConfDAO appConfDAO;

	@Autowired("blackIdCardDAO")
	private BlackIdCardDAO blackIdCardDAO;

    @Autowired("registOrderInfoDAO")
    private RegistOrderInfoDAO registOrderInfoDAO;

	public UserDAO getUserDAO() {
		return userDAO;
	}

	public void setUserDAO(UserDAO userDAO) {
		this.userDAO = userDAO;
	}

	public MessageDAO getMessageDAO() {
		return messageDAO;
	}

	public void setMessageDAO(MessageDAO messageDAO) {
		this.messageDAO = messageDAO;
	}

	public WebUserDAO getWebUserDAO() {
		return webUserDAO;
	}

	public void setWebUserDAO(WebUserDAO webUserDAO) {
		this.webUserDAO = webUserDAO;
	}

	public BlackIdCardDAO getBlackIdCardDAO() {
		return blackIdCardDAO;
	}

	public void setBlackIdCardDAO(BlackIdCardDAO blackIdCardDAO) {
		this.blackIdCardDAO = blackIdCardDAO;
	}

	@Override
	public String login(JSONObject json, String hostIp) {
		// Deprecated 兼容老版本
		final String userId = json.containsKey("userId") ? json.getString("userId") : "";
		final String authCode = json.getString("authCode");
		final String osVersion = json.getString("osVersion");
		final String appVersion = json.getString("appVersion");
		final String osType = json.getString("osType");
		final String phoneType = json.getString("phoneType");
		final String net = json.getString("net");
		final String applicationID = json.getString("applicationID"); // 应用ID
		final String packageName = json.getString("packageName");
		final long timestamp = json.getLongValue("timestamp");
		// 登录类型：0. 短信验证码登录
		final String type = json.containsKey("type") ? json.getString("type") : "";
		final String phone = json.containsKey("phone") ? json.getString("phone") : "";
		final String token = json.getString("token");
		System.out.println(json.getString("boryaAuth"));
		final String boryaAuthStr = json.getString("boryaAuth");
		HeaderEntity authHeader = JSONObject.parseObject(boryaAuthStr, HeaderEntity.class);

		final String key = userId.trim().length() == 0 ? json.getString("phone") : userId;
		String decryptToken;// = EncryptUtils.decrypt(key,
		// timestamp,packageName, token);
		if (Objects.nonNull(authHeader) && "1".equals(authHeader.getAppType())) {
			if (1 == authHeader.getOsType()) {// ios
				if (authHeader.getAppVersion() < 2019042500) {
					return StatusCode.UPGRADE.toJSON();
				}
				if (authHeader.getAppVersion() < 2019051600) {
					decryptToken = EncryptUtils.decrypt(key, timestamp, packageName, token);
				} else {
					decryptToken = EncryptUtils.decryptNew(key, timestamp, packageName, token);
				}
			} else if (2 == authHeader.getOsType()) {// android
				if (authHeader.getAppVersion() < 2019051600) {
					decryptToken = EncryptUtils.decrypt(key, timestamp, packageName, token);
				} else {
					decryptToken = EncryptUtils.decryptNew(key, timestamp, packageName, token);
				}
			} else {
				log.error("请求头osType错误" + authHeader);
				return StatusCode.PARAM_ERROR.toJSON("");
			}
		} else {
			decryptToken = EncryptUtils.decrypt(key, timestamp, packageName, token);
		}

		if (StringUtils.isBlank(authCode) || timestamp == 0) {
			log.warn("参数错误,type=" + type + "," + json);
			return StatusCode.PARAM_ERROR.toJSON("请输入验证码!");
		}

		if (decryptToken == null || decryptToken.trim().length() == 0) {
			log.warn("参数错误,token decrypt error,token=" + token + "," + json);
			return StatusCode.PARAM_ERROR.toJSON("请求错误");
		}
		final String[] tokens = decryptToken.split(",", -1);
		if (tokens == null || tokens.length < 6) {
			log.warn("[" + hostIp + "] Illegal token,token=" + token);
			return StatusCode.FORBID.toJSON("TOken解析错误");
		}

		final String longitude = tokens.length > 7 ? tokens[7].trim() : "0";
		final String latitude = tokens.length > 8 ? tokens[8].trim() : "0";

		User user = null;
		if (phone.trim().length() > 0) {
			user = getUserDAO().getUserByPhone(phone);
		} else if (userId.trim().length() > 0) {
			user = getUserDAO().getUser(userId);
		}

		if (user == null) {
			log.warn("用户:" + userId + " 未注册");
			return StatusCode.USER_NOT_FOUND.toJSON("您还未注册，请点击“创建账号”快来注册！");
		}

		if (user.getFlag() == com.borya.model.db.Flag.DELETED) {
			log.warn("用户:" + userId + " 被删除");
			return StatusCode.USER_NOT_FOUND.toJSON("您还未注册，请点击“创建账号”快来注册！");
		}

		Merchant merchant = getUserDAO().getMerchant(user.getDealerId());
		String result = processFlag(merchant);
		if (result != null) {
			return result;
		}
		Boolean blackFlag = getUserDAO().checkBlackUser(user.getUserId());
		if (blackFlag == null) {
			log.warn("查询黑名单返回null");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
		if (blackFlag) {
			log.warn("黑名单用户,userid:" + user.getUserId());
			return StatusCode.USER_NOT_FOUND.toJSON("您已被加入黑名单，解封请联系管理员");
		}
		if (user.getSourceType() == 2) {
			// 远特时空用户
			log.warn("用户:" + userId + " 为远特时空用户");
			return StatusCode.USER_NOT_FOUND.toJSON("该号码非卡盟账号！");
		}

		/** TODO IOS 审核测试账号 **/
		if ("17092510264".equals(user.getUserId()) && "170414".equals(authCode)) {
			log.info("[CHECK] :" + json);
		} else {
			// 验证码验证
			result = checkSmsCode(user.getUserId(), authCode);
			if (result != null) {
				return result;
			}
		}

		final long curTime = System.currentTimeMillis();
		user.setApplicationID(applicationID);
		user.setAppVersion(appVersion);
		user.setNet(net);
		user.setOsType(osType);
		user.setOsVersion(osVersion);
		user.setPhoneType(phoneType);
		user.setPackageName(packageName);
		user.setTmsi(curTime);
		user.setLastTime(curTime);
		user.setHostIp(hostIp);
		user.setLatitude(latitude);
		user.setLongitude(longitude);
		// 3.登录成功后，更新用户登录信息，
		boolean update = getUserDAO().updateUser(user);

		if (!update) {
			log.warn("更新客户端用户的信息失败");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}

		// //4.登录记录表存入登录信息,记录用户登录次数
		// String result = saveAllLoginData(userId, osVersion, appVersion,
		// osType, phoneType, net,
		// applicationID, packagename, curTime);
		// if(!result.equals("OK")) {
		// return result;
		// }

		/** 如果是游客账户，sign 2游客3审核中 **/
		String sign = String.valueOf(merchant.getIsSignAgreement());
		if (merchant.getStatus() != 0) {
			sign = "2";
			// if(3 == merchant.getStatus())
			// sign = "3";
		}
		/** 如果是游客账户，sign 2游客3审核中 **/
		JSONObject dtJson = new JSONObject();
		dtJson.put("tmsi", String.valueOf(curTime));
		dtJson.put("cityCode", user.getCityCode());
		dtJson.put("cityName", user.getCityName());
		dtJson.put("inviteCode", user.getInviteCode());
		dtJson.put("userName", user.getUserName());
		dtJson.put("sign", sign);
		dtJson.put("leftFee", user.getLeftFee());
		dtJson.put("userId", user.getUserId());
		dtJson.put("attribute", String.valueOf(merchant.getMerchant_attribute()));
		dtJson.put("attributeStatus", String.valueOf(merchant.getAttribute_status()));
		return StatusCode.SUCCESS.toDiyJson(true, "data", dtJson.toJSONString());
	}

	private String processFlag(Merchant merchant) {
		if (merchant == null) {
			log.warn("商户:" + merchant + " 未注册");
			return StatusCode.USER_NOT_FOUND.toJSON("您还未注册，请点击“创建账号”快来注册！");
		}
		if (merchant.getDealerId() == null || merchant.getDealerId().trim().length() == 0) {
			log.warn("商户:" + merchant + " 未注册");
			return StatusCode.USER_NOT_FOUND.toJSON("您还未注册，请点击“创建账号”快来注册！");
		}
		switch (merchant.getFlag()) {
		case Merchant.Flag.WRITE_OFF:
			log.warn("商户已注销," + merchant);
			return StatusCode.USER_NOT_FOUND.toJSON("您所在商户已被注销,具体请联系管理员！");
		default:
			break;
		}
		return null;
	}

	@Override
	public String getSmsCode(JSONObject json) {
		// @Deprecated
		final String userId = json.containsKey("userId") ? json.getString("userId") : "";
		final String osType = json.getString("osType");
		final String phone = json.containsKey("phone") ? json.getString("phone") : "";
		final String packageName = json.getString("packageName");
		if (StringUtils.isBlank(osType) || !"1,2".contains(osType)) {
			log.warn("ostype参数错误,packageName=" + packageName);
			return StatusCode.PARAM_ERROR.toJSON();
		}

		User user = null;
		if (phone.trim().length() > 0) {
			user = getUserDAO().getUserByPhone(phone);
		} else if (userId.trim().length() > 0) {
			user = getUserDAO().getUser(userId);
		}
		// 根据type类型，做逻辑判断
		if (user == null) {
			log.warn(userId + "用户还没有注册");
			return StatusCode.USER_NOT_FOUND.toJSON("您还未注册，请点击“创建账号”快来注册！");
		}
		if (user.getFlag() == com.borya.model.db.Flag.DELETED) {
			log.warn("用户:" + userId + " 被删除");
			return StatusCode.USER_NOT_FOUND.toJSON("用户未注册");
		}
		if (user.getSourceType() == 2) {
			// 远特时空用户
			log.warn("用户:" + userId + " 为远特时空用户");
			return StatusCode.USER_NOT_FOUND.toJSON("该号码非卡盟账号！");
		}

		Merchant merchant = getUserDAO().getMerchant(user.getDealerId());
		String result = processFlag(merchant);
		if (result != null) {
			return result;
		}

		Boolean blackFlag = getUserDAO().checkBlackUser(user.getUserId());
		if (blackFlag == null) {
			log.warn("查询黑名单返回null");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
		if (blackFlag) {
			log.warn("黑名单用户,userid:" + user.getUserId());
			return StatusCode.USER_NOT_FOUND.toJSON("您已被加入黑名单，解封请联系管理员");
		}
		return process_sms(user.getUserId(), user.getPhone(), osType);
	}

	/**
	 * 向用户手机发送一条动态验证码
	 *
	 * @param phone
	 * @param osType
	 * @return
	 */
	private String process_sms(String userId, String phone, String osType) {
		final long curTime = System.currentTimeMillis();
		SmsInfo smsInfo = SMC_CODE_MAP.get(phone);
		// 短信内容不存在，或者超时了，重新发送
		if (smsInfo == null || smsInfo.getTimeoutTime() < curTime) {
			String authCode = StringUtil.randomNumberString(6);
			if (Constant.IS_TEST) {
				authCode = "666666";
				log.info("测试环境，验证码写死");
			}
			String content = "尊敬的用户,您本次的短信动态码为:" + authCode + "，如非本人操作,请忽略本次通知。";
			boolean ok = sendMsg(phone, content);
			if (ok) {
				SmsInfo smsInfo2 = new SmsInfo();
				smsInfo2.setAuthCode(authCode);
				smsInfo2.setTimeoutTime(curTime + SMS_TIMEOUT);
				smsInfo2.setRequesttype(osType);

				SMC_CODE_MAP.put(userId, smsInfo2);
				log.info("[SMS] 向用户:" + phone + "发送短信验证码成功");
				return StatusCode.SUCCESS.toJSON();
			} else {
				log.info("[SMS] 向用户：" + phone + "发送短信验证码失败");
				return StatusCode.SYSTEM_EXCEPTION.toJSON("获取短信验证码失败，请稍后再试");
			}
		} else {
			log.info("[SMS] 短信验证码已向用户：" + phone + "发送出去了");
			return StatusCode.SUCCESS.toJSON("您的短信验证码已经发送到你手机上了，请注意查收");
		}
	}

	private String checkSmsCode(final String userId, String authCode) {
		final long curTime = System.currentTimeMillis();
		SmsInfo smsInfo = SMC_CODE_MAP.get(userId);
		if (smsInfo == null) {
			log.warn(userId + "的短信内容不存在");
			return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码已失效，请重新获取");
		} else {
			int useNum = smsInfo.getUseNum() + 1;
			smsInfo.setUseNum(useNum);
			SMC_CODE_MAP.put(userId, smsInfo);
			if (useNum >= 1 && useNum <= 3) {
				String authCode2 = smsInfo.getAuthCode();
				if (!authCode.equals(authCode2) && smsInfo.getTimeoutTime() > curTime) { // 验证码错误，但是没有超时
					log.warn("验证码错误.用户上传的验证码：【" + authCode + "】，平台保存的验证码：【" + authCode2 + "】");
					return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码错误，请重新输入");
				} else if (smsInfo.getTimeoutTime() < curTime) { // 验证码正确，但超时
					log.warn("用户获取验证码到校验验证码超时");
					return StatusCode.CAPTCHE_NOT_FOUND.toJSON("校验验证码超时，请重新获取验证码");
				} else {
					// success
					return null;
				}
			} else {
				SMC_CODE_MAP.remove(userId);
				return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码已失效，请重新获取验证码");
			}
		}
	}

	@Override
	public String loginout(JSONObject json) {
		String userId = json.getString("userId");
		if (StringUtil.isNULL(userId)) {
			return StatusCode.PARAM_ERROR.toJSON("参数错误");
		}
		getUserDAO().updateTmsi(userId, "0");
		return StatusCode.SUCCESS.toJSON();
	}

	@Override
	public String userInfo(User user, JSONObject json) {
		final String dealerId = user.getDealerId();
		Object[] obj = getUserDAO().getMerchantInfo(dealerId);
		if (obj == null) {
			log.error("DB connection exception.");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
		final Merchant merchant = (Merchant) obj[0];
		String privacyTime = "";
		if (0L < merchant.getRegistTime()) {
			// 商户签订隐私协议时间
			MerchantDetailInfo info = userDAO.getMerchantDetail(user.getMerchantId());
			if (Objects.nonNull(info)) {
				privacyTime = Objects.isNull(info.getRatifyAccordTime()) ? ""
						: Long.toString(info.getRatifyAccordTime());
			}
		}
		final Integer num = (Integer) obj[1];
		final Integer lowerMerchantCount = (Integer) obj[2];
		MerchantLevelInfo merchantLevel = getUserDAO().getMerchantLevel(dealerId);
		merchantLevel.setCreditPoints();
		merchantLevel.setMerchantLevel();
		merchantLevel.setNeedSuccessNums();
		// 查询信用等级配置
		MerchantLevelConfig m = getUserDAO().getMerchantLevelConfig();
		/** 如果是游客账户，sign 2 未激活3激活审核中 **/
		String sign = String.valueOf(merchant.getIsSignAgreement());
		if (0 != merchant.getStatus()) {
			if (3 == merchant.getStatus())
				sign = "3";
			else
				sign = "2";
		}

		/** 如果是游客账户，sign返回2 **/
		StringBuilder sb = new StringBuilder();
		sb.append("{");
		sb.append("\"userName\":\"" + user.getUserName() + "\"");
		sb.append(",\"cityName\":\"" + user.getCityName() + "\"");
		sb.append(",\"cityCode\":\"" + user.getCityCode() + "\"");
		sb.append(",\"userId\":\"" + user.getUserId() + "\"");
		sb.append(",\"phone\":\"" + user.getPhone() + "\"");
		// @Deprecated
		// userNatureId 兼容老ios,废弃
		sb.append(",\"userNatureId\":\"个人\"");
		// @Deprecated
		// userTypeId 兼容老ios,废弃
		sb.append(",\"userTypeId\":\"" + merchant.getUserTypeName() + "\"");
		sb.append(",\"alipayUserId\":\"" + user.getAlipayUserId() + "\"");
		sb.append(",\"weixinUserId\":\"" + parseAccountId(user.getWeixinUserId()) + "\"");
		sb.append(",\"alipayUserName\":\"" + user.getAlipayUserName() + "\"");
		sb.append(",\"mainAccount\":\"" + user.getIsMain() + "\"");
		sb.append(",\"createTime\":\"" + parseTime(user.getCreateTime()) + "\"");
		sb.append(",\"inviteCode\":\"" + user.getInviteCode() + "\"");

		sb.append(",\"merchantInfo\":{");
		sb.append("\"dealerId\":\"" + dealerId + "\"");
		sb.append(",\"companyName\":\"" + merchant.getCompanyName() + "\"");
		sb.append(",\"address\":\"" + merchant.getAddress() + "\"");
		sb.append(",\"storeAddress\":\"" + merchant.getStoreAddress() + "\"");
		sb.append(",\"merchantType\":\"" + merchant.getMerchantType() + "\"");
		sb.append(",\"natureId\":\"" + merchant.getUserTypeId() + "\"");
		sb.append(",\"natureNickName\":\"" + merchant.getUserTypeName() + "\"");
		sb.append(",\"createTime\":\"" + parseTime(merchant.getCreateTime()) + "\"");
		sb.append(",\"sign\":\"" + sign + "\"");
		sb.append(",\"signTime\":\"" + parseTime(merchant.getSignTime()) + "\"");
		sb.append(",\"privacyTime\":\"" + privacyTime + "\"");
		sb.append(",\"ymDepid\":\"" + merchant.getYmDepid() + "\"");
		sb.append(",\"ymStaffno\":\"" + merchant.getYmStaffno() + "\"");

		sb.append(",\"level\":\"" + merchantLevel.getMerchantLevel() + "\"");
		sb.append(",\"nextLevel\":\"" + merchantLevel.getNextLevel() + "\"");
		sb.append(",\"usePower\":\"" + merchantLevel.getPower(merchantLevel.getMerchantLevel(), m) + "\"");
		sb.append(",\"levelAllowUpd\":\"" + merchantLevel.getAllowUpd() + "\"");
		sb.append(",\"needNums\":\"" + merchantLevel.getNeedSuccessNums() + "\"");
		/******* 废弃 ********/
		// 普通用户/优质用户/vip
		// final int creditLevel =
		// parseCreditLevel(map_credit,merchant.getCreditNum());
		sb.append(",\"creditLevelDesc\":\"\"");
		sb.append(",\"creditLevel\":\"\"");
		sb.append(",\"creditNum\":\"\"");
		/******* 废弃 ********/

		sb.append(",\"lowerUserCount\":\"" + num + "\"");

		// 2018-04-11 商户权限详情
		Object[] attributeInfo = getUserDAO().merchantAttributeInfo(dealerId);
		if (attributeInfo == null) {
			log.warn("merchantAttributeInfo return null");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
		int scopeTot = (int) attributeInfo[0];
		sb.append(",\"attributeStr\":\"" + (scopeTot == 0 ? "无售卡权限" : attributeInfo[1]) + "\"");
		/******* 商户权限 ******/
		sb.append(",\"attribute\":\"" + merchant.getMerchant_attribute() + "\"");
		sb.append(",\"attributeStatus\":\"" + merchant.getAttribute_status() + "\"");
		/******* 商户权限 ******/
		// 2018-04-11 商户权限详情

		/**** 授权牌信息 ****/
		sb.append(",\"shqp\":{");
		addShqpInfo(dealerId, sb, user.getSourceType());
		sb.append("}");
		/**** 授权牌信息 ****/

		sb.append("}");
		// 查推广用户个数
		sb.append(",\"lowerMerchantCount\":\"" + lowerMerchantCount + "\"");

		sb.append("}");
		return StatusCode.SUCCESS.toDiyJson("data", sb);
	}

	private String parseTime(long time) {
		if (time == 0L) {
			return "-";
		}
		return DateUtils.format(time, "yyyy-MM-dd HH:mm");
	}

	private String parseAccountId(String accountId) {
		if (accountId == null) {
			return "未绑定";
		}

		return "".equals(accountId) ? "未绑定" : accountId;
	}

	@Override
	public String updateUser(User user, JSONObject json) {
		String cityCode = json.getString("cityCode");
		String cityName = json.getString("cityName");

		if (StringUtils.isBlank(cityCode) || StringUtils.isBlank(cityName)) {
			log.warn("cityCode：" + cityCode + ",cityName:" + cityName);
			return StatusCode.PARAM_ERROR.toJSON();
		}

		boolean flag = getUserDAO().updateUserCity(cityCode, cityName, user.getUserId());
		if (!flag) {
			return StatusCode.SYSTEM_EXCEPTION.toJSON("更新失败");
		}

		return StatusCode.SUCCESS.toJSON();
	}

	@Override
	public String signAgeeement(User user, JSONObject json) {
		final String userId = user.getUserId();
		final String signedPic = json.getString("signedPic");

		Merchant merchant = getUserDAO().getMerchant(user.getDealerId());
		if (merchant == null) {
			log.warn("商户：" + merchant + "未注册");
			return StatusCode.USER_NOT_FOUND.toJSON("您还未注册，请点击“创建账号”快来注册！");
		}
		if (merchant.getIsSignAgreement() == Merchant.SignAgreement.ALREADY_SIGN) {
			log.warn("merchant already sign,userId=" + userId);
			return StatusCode.SUCCESS.toJSON();
		}
		final String timeStr = DateUtils.format(System.currentTimeMillis(), "YYMMddHHmmssSSS");
		final String fileName = userId + "_" + timeStr;
		final String newImgName = fileName + ".png";
		final String phone = user.getPhone();
		// 合并图片的名称
		final String signMergePicture = fileName + "_merge.png";
		final String deviceId = merchant.getDevMac();
		try {
			FileInfo fileInfo = FileInfo.newInstance(Constant.SpecialTag.SIGN, "", newImgName);
			boolean ok = ImageUtils.writeImg(fileInfo.getParentPath(), fileInfo.getFileName(), signedPic);
			if (!ok) {
				return StatusCode.SYSTEM_EXCEPTION.toJSON("上传图片失败，请稍后重试");
			}
			// 图片签名
			saveImgNarrow(fileInfo.getFilePath(), fileInfo.getParentPath(), phone, deviceId, signMergePicture,
					merchant.getMerchant_attribute());
			// 图片存储oss
			ok = imgUploadOssAndRemoveDir(fileInfo.getRelatePath());
			boolean ok1 = imgUploadOssAndRemoveDir(fileInfo.getRelateDir() + signMergePicture);
			if (!ok || !ok1) {
				return StatusCode.SYSTEM_EXCEPTION.toJSON("上传图片oss失败，请稍后重试");
			}
			merchant.setSignPicture(fileInfo.getRelatePath());
			merchant.setSignMergePicture(fileInfo.getRelateDir() + signMergePicture);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}

		Boolean bool = getUserDAO().updateSignAgeeement(merchant.getDealerId(), merchant.getSignPicture(),
				merchant.getSignMergePicture());
		if (!bool) {
			log.error("DB connection exception.");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}

		return StatusCode.SUCCESS.toJSON();
	}

	/**
	 * 图片签名
	 *
	 * @param signImgPath
	 * @param destDir
	 * @param fileNameMerge
	 * @param merchantType
	 *            1远特2联通
	 * @return
	 * @throws Exception
	 */
	private boolean saveImgNarrow(final String signImgPath, final String destDir, String phone, String deviceId,
			String fileNameMerge, int merchantType) throws Exception {
		String narrowPath = "";
		switch (merchantType) {
		case 1:
			narrowPath = "/agent_merchant_agreement1.png";
			break;
		case 3:
			narrowPath = "/agent_merchant_agreement1.png";
			break;
		case 2:
		case 4:
			narrowPath = "/unicom_agreement.png";
			break;
		default:
			break;
		}
		log.info(String.format("文件相对位置: %s，当前类：%s", narrowPath, getClass().getSimpleName()));
		InputStream in = getClass().getResourceAsStream(narrowPath);

		final String signImgCopyPath = destDir + fileNameMerge + "_copy.png";
		File signImgCopyFile = new File(signImgCopyPath);
		// 文件拷贝
		FileUtils.copyFile(new File(signImgPath), signImgCopyFile);
		if (Objects.isNull(in)) {
			log.error(String.format("输入流不能为空，文件相对位置: %s", narrowPath));
			throw new RuntimeException("输入流不能为空");
		}
		Image src1 = javax.imageio.ImageIO.read(in);
		// 获取图片的宽度/高度
		final int width1 = src1.getWidth(null);

		Image src3 = javax.imageio.ImageIO.read(signImgCopyFile);
		final int width2 = src3.getWidth(null);
		final int height2 = src3.getHeight(null);
		if (width1 != width2) {
			// 等比缩放
			ImageUtils.narrowImage(signImgCopyPath, width1, (int) ((double) width1 / width2 * height2));
		} else {
			// Ignore
		}

		final String date = DateUtils.format("yyyy-MM-dd HH:mm:ss");
		// 图片水印
		// ImageUtils.waterMarkBySingleText(signImgCopyFile,signImgCopyFile,date+"
		// 签约人"+phone);

		List<String> list = new ArrayList<String>();
		list.add("签约时间:" + date);
		list.add("签约人:" + phone);
		if (deviceId != null && deviceId.length() > 0) {
			list.add("设备ID:" + deviceId);// YT620175200871
		}

		// destDir + fileNameMerge +"_copy.png";
		ImageUtils.createImg(destDir, fileNameMerge + "_water.png", list, width1);
		File file2 = new File(destDir + fileNameMerge + "_water.png");
		ImageUtils.mergeImageVertically(src1, file2, destDir + "/" + fileNameMerge + "_2.png");

		File fileTmpe2 = new File(destDir + "/" + fileNameMerge + "_2.png");
		Image src2_ = javax.imageio.ImageIO.read(fileTmpe2);

		// 图片合并
		Image src3_ = javax.imageio.ImageIO.read(signImgCopyFile);
		ImageUtils.mergeImageVertically(src2_, src3_, destDir + "/" + fileNameMerge);
		clearAndDeleteFile(signImgCopyFile);
		clearAndDeleteFile(fileTmpe2);
		clearAndDeleteFile(file2);
		return true;
	}

	private void clearAndDeleteFile(File file) {
		if (file == null) {
			return;
		}
		if (file.exists()) {
			try (FileOutputStream out = new FileOutputStream(file);) {
				out.write(new byte[1]);
			} catch (IOException e) {
				log.error(e.getMessage(), e);
			}
			file.delete();
		}
		file = null;
	}

	@Override
	public String getUserList(User user, JSONObject json) {
        final String boryaAuthStr = json.getString("boryaAuth");
        final String osType = json.getString("osType");
        final String appType = json.getString("appType");
        int backgroundVersion = getBackgroundVersion(appType, osType);
        HeaderEntity authHeader = JSONObject.parseObject(boryaAuthStr, HeaderEntity.class);
        SystemConfig instance = SystemConfig.getInstance();
        // IOS老版本不需要展示列表
        if (authHeader.getAppVersion() < backgroundVersion) {
            log.warn("app 版本低于服务器版本,appVersion=" + authHeader.getAppVersion() + ",serverVersion="
                    + instance.getInteger(AppSignTokenVersion.KA_MENG_IOS.getToken()));
            return StatusCode.NO_REGIST_ERR.toJSON("该功能正在维护,敬请期待。");
        }
        JSONObject jsonObject = new JSONObject();
        final String merchantId = user.getMerchantId();
		if (user.getIsMain() != 1) {
			log.warn("不是主账号不能查看子账号信息");
			return StatusCode.FORBID.toJSON("子账号不能查看列表信息");
		}

        List<UserDataModel> userList = getUserDAO().getUserList(merchantId);
        if (Objects.isNull(userList) || 0 == userList.size()) {
			log.error("DB connection exception.");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
        List<JobNumberAuditModel> auditList = getUserDAO().getJobNumberAuditList(merchantId, 1);
        jsonObject.put("auditList", auditList);
        jsonObject.put("userList", userList);

        Merchant merchant = merchantDAO.getByMerchantId(user.getMerchantId());
        if (Objects.isNull(merchant)) {
            log.error("DB 连接异常,merchantId=" + user.getMerchantId());
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }
        int count;
        if (1 == merchant.getMerchantType()) {
            count = Constant.COMPANY_SON_JOB_NUM_COUNT - 1;
        } else {
            count = Constant.PERSONAL_SON_JOB_NUM_COUNT - 1;
        }
        jsonObject.put("hintCont", String.format(Constant.HINT_CONT, count));
        jsonObject.put("sonJobNum", String.valueOf(count));

        return StatusCode.SUCCESS.toDiyJson("data", jsonObject);
    }

    @Override
    public String getUserDetailList(User user, JSONObject json) {
        final String userId = json.getString("requestUserId");
        if (StringUtils.isBlank(userId)) {
            log.warn("param userId is null");
            return StatusCode.PARAM_ERROR.toJSON("商户ID不能为空");
        }

        UserDetailModel detailModel = getUserDAO().getUserDetailList(userId);
        if (Objects.isNull(detailModel)) {
            log.error("DB connection exception,userId is " + userId);
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }

        return StatusCode.SUCCESS.toDiyJson(true, "data", JSONObject.toJSONString(detailModel));
    }

    @Override
    public String getManageLogList(User user, JSONObject json) {
        final String dealerId = user.getDealerId();
        if (user.getIsMain() != 1) {
            log.warn("不是主账号不能查看管理日志信息");
            return StatusCode.FORBID.toJSON("子账号不能查看管理日志信息");
        }
        List<ManageLogModel> manageLogList = getUserDAO().getManageLogList(dealerId);
        if (Objects.isNull(manageLogList) || 0 == manageLogList.size()) {
            log.warn("manageLogList is null,dealerId is " + dealerId);
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", manageLogList);
        return StatusCode.SUCCESS.toDiyJson("data", jsonObject);
    }

    @Override
    public String getUploadImgConfig(JSONObject json) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("uploadConfig", Constant.UPLOAD_IMG_CONFIG);
        return StatusCode.SUCCESS.toDiyJson("data", jsonObject);
    }

	private String userInfoAppend(List<User> list) {
		StringBuilder sb = new StringBuilder(256);
		Collections.sort(list, new Comparator<User>() {
			@Override
			public int compare(User u1, User u2) {
				return (u1.getCreateTime() > u2.getCreateTime()) ? 1 : 0;
			}
		});
		for (User u : list) {
			sb.append(",");
			sb.append("{");
			sb.append("\"userName\":\"" + u.getUserName() + "\"");
			sb.append(",\"cityName\":\"" + u.getCityName() + "\"");
			sb.append(",\"mainAccount\":\"" + u.getIsMain() + "\"");
			sb.append(",\"cityCode\":\"" + u.getCityCode() + "\"");
			sb.append(",\"userId\":\"" + u.getUserId() + "\"");
			sb.append(",\"phone\":\"" + u.getPhone() + "\"");
			sb.append(",\"createTime\":\"" + parseCreateTime(u.getCreateTime()) + "\"");
			sb.append(",\"account\":\"" + u.getLeftFee() + "\"");
			sb.append(",\"deductionFee\":\"").append(u.getDeduction_fee()).append("\"");
			sb.append("}");
		}
		return sb.toString();
	}

	private String parseCreateTime(long time) {
		if (time == 0L) {
			return "-";
		}
		return DateUtils.format(time, "yyyy-MM-dd HH:mm:ss");
	}

	@Override
	public String getBindPhoneCode(User user, JSONObject json) {
		final String userId = user.getUserId();
		final String newPhone = json.getString("newPhone");
		if (newPhone == null || newPhone.trim().length() < 1) {
			log.warn("user new_phone error," + json);
			return StatusCode.PARAM_ERROR.toJSON("新的绑定号码格式错误");
		}
		String check = checkBindPower(newPhone);
		if (check != null) {
			return check;
		}
		return process_sms(userId, newPhone, "-");
	}

	@Override
	public String bindPhone(User user, JSONObject json) {
		final String userId = user.getUserId();
		final String newPhone = json.getString("newPhone");
		final String authCode = json.getString("authCode");
		if (newPhone == null || newPhone.trim().length() < 1) {
			log.warn("user new_phone error," + json);
			return StatusCode.PARAM_ERROR.toJSON("新的绑定号码格式错误");
		}
		if (authCode == null || authCode.trim().length() < 1) {
			log.warn("user authCode  error," + json);
			return StatusCode.PARAM_ERROR.toJSON("短信验证码格式错误");
		}
		String check = checkBindPower(newPhone);
		if (check != null) {
			return check;
		}

		String result = checkSmsCode(userId, authCode);
		if (result != null) {
			return result;
		}

		log.debug("user bind phone=" + newPhone);
		boolean bool = getUserDAO().bindPhone(userId, newPhone);
		if (bool) {
			log.warn("user bind phone success,phone=" + newPhone);
			return StatusCode.SUCCESS.toJSON();
		} else {
			log.warn("更新客户端用户的信息失败");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	private String checkBindPower(String newPhone) {
		User user = userDAO.getUserByPhone2(newPhone);
		if (user == null) {
			log.warn("getUserByPhone2 return null," + newPhone);
		}
		if (ObjectUtils.nonNullOrEmpty(user.getDealerId())) {
			log.warn("phone已有用户," + user.toString());
			return StatusCode.USERNAME_EXISTED.json().msg("该号码已被使用。").toString();
		}
		return null;
	}

	@Override
	public String removeUser(User user, JSONObject json) {
		try {
            final String removeUserId = json.getString("removeUserId");
            if (StringUtil.isNULL(removeUserId)) {
				log.warn("param removeUserId error");
				return StatusCode.PARAM_ERROR.toJSON("参数 工号 错误");
			}
			if (user.getIsMain() != 1) {
				log.warn("非主工号 removeUser");
				return StatusCode.PERMISSIONPROFILE_IS_NULL.toJSON();
			}

            User removeUser = getUserDAO().getUser(removeUserId);
			if (removeUser == null) {
				log.warn("getUser return null,userid:" + removeUserId);
				return StatusCode.STAFF_NOT_FOUND.toJSON();
			}
			if (Constant.remove_with_account == 2) {
				if (removeUser.getLeftFee() != 0) {
					log.warn("有余额不允许删除子工号");
					return StatusCode.NO_AUTHORITY.toJSON("此工号内仍有余额，不允许删除。");
				}
			}
			if (!removeUser.getDealerId().equals(user.getDealerId())) {
				log.warn("非统一商户号");
				return StatusCode.NO_AUTHORITY.toJSON("不允许删除其他商户子工号");
			}
			if (removeUser.getIsMain() == 1) {
				log.warn("主工号，" + removeUserId);
				return StatusCode.NO_AUTHORITY.toJSON("主账号不允许删除");
			}
			Long left_fee = getUserDAO().getLeftFee(user.getUserId());
			if (left_fee == null) {
				log.warn("getLeftFee return null,userid:" + user.getUserId());
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			user.setLeftFee(left_fee);
			String order_id = "DE" + createSysOrderId();
			// 用户的删除标志
			removeUser.setFlag(Flag.DELETED);
			Boolean r = getUserDAO().removeUser(removeUser, user, order_id);
			if (r == null || r.equals(false)) {
				log.warn("removeUser return " + r + "," + r.toString());
				return StatusCode.SYSTEM_EXCEPTION.toJSON("系统繁忙，请稍候再试");
			}
			String content = "您的工号已被删除,账户余额" + new BigDecimal(removeUser.getLeftFee()).divide(new BigDecimal(100), 2)
					+ "元已转入主工号" + user.getUserName() + "(电话:" + user.getPhone() + ")中。";
			sendMsg(removeUser.getPhone(), content);
			return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

    private String checkSonJobNumCount(String merchantId, Integer merchantType) {
        // 判断已经存在工号和在途子工号一共有多少个
        int count = 0;
        List<UserDataModel> userList = userDAO.getUserList(merchantId);
        if (Objects.nonNull(userList)) {
            count += userList.size();
        }
        List<JobNumberAuditModel> jobNumberAuditList = userDAO.getJobNumberAuditList(merchantId, 1);
        if (Objects.nonNull(jobNumberAuditList)) {
            count += jobNumberAuditList.size();
        }
        if (merchantType.equals(1)) {
            // 企业
            if (count >= Constant.COMPANY_SON_JOB_NUM_COUNT) {
                log.error("该用户子工号达到上限,dealerId为" + merchantId);
                return StatusCode.SYSTEM_EXCEPTION.toJSON("该用户子工号达到上限,如需操作请联系管理员");
            }
        } else {
            // 个人
            if (count >= Constant.PERSONAL_SON_JOB_NUM_COUNT) {
                log.error("该用户子工号达到上限,dealerId为" + merchantId);
                return StatusCode.SYSTEM_EXCEPTION.toJSON("该用户子工号达到上限,如需操作请联系管理员");
            }
        }
        return null;
    }

    // 通过身份证号码判断该身份证号码已经存在工号和在途子工号一共有多少个
    private String checkSonJobNumCountByIdCard(String merchantId, String idCard, Integer merchantType, Integer detailType) {
        int count = 0;
        List<UserDataModel> userDetailList = userDAO.getUserDetailListByIdCard(idCard, detailType);
        if (Objects.nonNull(userDetailList)) {
            count += userDetailList.size();
        }
        List<JobNumberAuditModel> jobNumberAuditList = userDAO.getJobNumberAuditListByIdCard(idCard);
        if (Objects.nonNull(jobNumberAuditList)) {
            count += jobNumberAuditList.size();
        }
        if (merchantType.equals(2)) {
            // 个人
            if (count >= Constant.PERSONAL_SON_JOB_NUM_COUNT) {
                log.error("该用户子工号达到上限,idCard为" + idCard);
                return StatusCode.SYSTEM_EXCEPTION.toJSON("该用户子工号达到上限,如需操作请联系管理员");
            }
        } else {
            // 企业
            if (count >= Constant.COMPANY_SON_JOB_NUM_COUNT) {
                log.error("该用户子工号达到上限,idCard为" + idCard);
                return StatusCode.SYSTEM_EXCEPTION.toJSON("该用户子工号达到上限,如需操作请联系管理员");
            }
        }
        return null;
    }

    private String checkIdCardIsBlack(String idCard) {
        // 判断身份证黑名单
        final boolean res = blackIdCardDAO.idCardUsed(idCard);
        if (!res) {
            log.error("商户被加入身份证名单tb_black_idcard,idCard=" + idCard);
            return StatusCode.SYSTEM_EXCEPTION.toJSON("身份证异常,请联系管理员");
        }
        return null;
    }

	@Override
	public String getCreateCode(User user, JSONObject json) {
		try {
			final String phone = json.getString("phone");
			final String idCard = json.getString("idCard");
			if (phone == null || phone.length() != 11) {
				return StatusCode.PARAM_ERROR.toJSON("电话号码错误");
			}
			if (idCard != null && idCard.length() == 0) {
				return StatusCode.PARAM_ERROR.json().msg("证件号未上传").toString();
			}
			if (user.getIsMain() != 1) {
				log.warn("非主工号 removeUser");
				return StatusCode.PERMISSIONPROFILE_IS_NULL.toJSON();
			}
			User userDB = getUserDAO().getUserByPhone2(phone);
			String checkPhone = checkPhone(phone, userDB);
			if (checkPhone != null) {
				return checkPhone;
			}
			if (ObjectUtils.nonNullOrEmpty(idCard)) {
				String checkIdCardBlack = checkIdCardIsBlack(idCard);
				if (checkIdCardBlack != null) {
					return checkIdCardBlack;
				}
			}

            Merchant merchant = merchantDAO.getByMerchantId(user.getMerchantId());
            if (Objects.isNull(merchant)) {
                log.error("DB 连接异常，merchantId=" + user.getMerchantId());
                return StatusCode.SYSTEM_EXCEPTION.toJSON();
            }

            // 校验存在几个工号(包括在途、主工号)
            String checkSonJobNumCount = checkSonJobNumCount(user.getMerchantId(), merchant.getMerchantType());
            if (StringUtils.isNotBlank(checkSonJobNumCount)) {
                return checkSonJobNumCount;
            }

            // 校验手机号是否已经注册过（在途）
            String checkPhoneByState = checkPhoneByState(phone);
            if (StringUtils.isNotBlank(checkPhoneByState)) {
                return checkPhoneByState;
            }

            //校验该证件号是否注册过子工号
            String checkIdCard = checkIdCardIsMain(idCard, user.getDetailType());
            if (StringUtils.isNotBlank(checkIdCard)) {
                return checkIdCard;
            }

            // 校验身份证号是否存在审核表
            String checkIdCardForAudit = checkIdCardForAudit(idCard);
            if (StringUtils.isNotBlank(checkIdCardForAudit)) {
                return checkIdCardForAudit;
            }
			String key = user.getUserId() + phone;
			Long t = getUserDAO().redis_ttl(RedisConstant.REDIS_NAME_SPACE + key);
			if (t == null || t < 20) {
				String code = StringUtil.randomNumberString(6);
				if (Constant.IS_TEST) {
					log.info("测试环境，验证码写死");
					code = "666666";
				}
				String content = "尊敬的用户,您手机号的开户验证码为：" + code + "。";
				boolean s = sendMsg(phone, content);
				if (!s) {
					return StatusCode.SYSTEM_EXCEPTION.toJSON("验证码发送失败，请稍候再试");
				}
				getUserDAO().redis_set(RedisConstant.REDIS_NAME_SPACE + key, code);
				getUserDAO().redis_expire(RedisConstant.REDIS_NAME_SPACE + key, 120);

			}
			return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String createUser(User user, JSONObject json) {
		final String phone = json.getString("phone");
        if (StringUtils.isBlank(phone) || phone.length() != 11) {
			return StatusCode.PARAM_ERROR.toJSON("电话号码错误");
		}
		final String keyLock = RedisConstant.CREATE_USER + phone;
		if (!userDAO.redis_setNx(keyLock, "1")) {
			log.warn("并发请求，" + json);
			return StatusCode.CONDITION_DEL_ING.json().msg("操作过快，请稍后再试").toString();
		}
		userDAO.redis_expire(keyLock, 120);
		try {
            final String name = json.getString("name");
            final String idCard = json.getString("idCard");
            final String idAddress = json.getString("idAddress");
            final String period = json.getString("period");
            final String cityCode = json.getString("cityCode");
            final String cityName = json.getString("cityName");
            final String relationType = json.getString("relationType");
            final String identifyPhotoFront = json.getString("identifyPhotoFront");
            final String identifyPhotoReverse = json.getString("identifyPhotoReverse");
            final String identifyPhotoHand = json.getString("identifyPhotoHand");
            final String identifyPhotoHead = json.getString("identifyPhotoHead");
            final String signPicture = json.getString("signPicture");
            final String reqCode = json.getString("code");
            final String osType = json.getString("osType");

            if (StringUtils.isBlank(idCard)) {
				return StatusCode.PARAM_ERROR.json().msg("证件号未上传").toString();
			}
            if (StringUtils.isBlank(idAddress)) {
				return StatusCode.PARAM_ERROR.json().msg("证件地址未上传").toString();
			}
			if (StringUtils.isBlank(name)) {
				return StatusCode.PARAM_ERROR.toJSON("开户姓名错误");
			}
			if (StringUtils.isBlank(reqCode)) {
				return StatusCode.PARAM_ERROR.toJSON("验证码错误");
			}
			if (StringUtils.isBlank(cityCode)) {
				return StatusCode.PARAM_ERROR.toJSON("参数 城市编码 错误");
			}
			if (StringUtils.isBlank(cityName)) {
				return StatusCode.PARAM_ERROR.toJSON("参数 城市名 错误");
			}
            if (StringUtils.isBlank(relationType)) {
                return StatusCode.PARAM_ERROR.json().msg("关系类型未上传").toString();
            }
            if (StringUtils.isBlank(identifyPhotoFront)) {
                return StatusCode.PARAM_ERROR.json().msg("身份证正面照未上传").toString();
            }
            if (StringUtils.isBlank(identifyPhotoReverse)) {
                return StatusCode.PARAM_ERROR.json().msg("身份证背面照未上传").toString();
            }
            if (StringUtils.isBlank(identifyPhotoHand)) {
                return StatusCode.PARAM_ERROR.json().msg("手持证件照未上传").toString();
            }
            if (StringUtils.isBlank(identifyPhotoHead)) {
                return StatusCode.PARAM_ERROR.json().msg("身份证大头照未上传").toString();
            }
            if (StringUtils.isBlank(signPicture)) {
                return StatusCode.PARAM_ERROR.json().msg("签名图片未上传").toString();
            }
			if (user.getIsMain() != 1) {
				return StatusCode.PERMISSIONPROFILE_IS_NULL.toJSON();
			}
			String key = user.getUserId() + phone;
			String code = getUserDAO().redis_get(RedisConstant.REDIS_NAME_SPACE + key);
            if (StringUtils.isBlank(code)) {
				return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码已失效，请重新获取");
			}
			if (ObjectUtils.nonEqual(code, reqCode)) {
				return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码错误");
			}

            Merchant merchant = merchantDAO.getByMerchantId(user.getMerchantId());
            if (Objects.isNull(merchant)) {
                log.error("DB 连接异常,merchantId=" + user.getMerchantId());
                return StatusCode.SYSTEM_EXCEPTION.toJSON();
            }

            // 校验存在几个工号(包括在途、主工号)
            String checkSonJobNumCount = checkSonJobNumCount(user.getMerchantId(), merchant.getMerchantType());
            if (StringUtils.isNotBlank(checkSonJobNumCount)) {
                return checkSonJobNumCount;
            }

            // 校验身份证是否黑名单
            String checkIdCardBlack = checkIdCardIsBlack(idCard);
            if (StringUtils.isNotBlank(checkIdCardBlack)) {
                return checkIdCardBlack;
            }
            //校验该手机号是否已经注册过
            User userDB = getUserDAO().getUserByPhone2(phone);
			String checkPhone = checkPhone(phone, userDB);
            if (StringUtils.isNotBlank(checkPhone)) {
				return checkPhone;
			}

            // 校验手机号是否已经注册过（在途）
            String checkPhoneByState = checkPhoneByState(phone);
            if (StringUtils.isNotBlank(checkPhoneByState)) {
                return checkPhoneByState;
            }

            //校验该证件号是否注册过子工号
            String checkIdCard = checkIdCardIsMain(idCard, user.getDetailType());
            if (StringUtils.isNotBlank(checkIdCard)) {
				return checkIdCard;
			}

            // 校验身份证号是否存在审核表
            String checkIdCardForAudit = checkIdCardForAudit(idCard);
            if (StringUtils.isNotBlank(checkIdCardForAudit)) {
                return checkIdCardForAudit;
            }

            Long nowTime = Clock.systemDefaultZone().millis();
            String orderId = Constant.ADD_JOB_NUM + DateUtils.format(nowTime, "yyMMddHHmmss") + user.getPhone().substring(4);
            JobNumberAudit audit = new JobNumberAudit();
            audit.setOrderId(orderId);
            audit.setUserId(getUserId());
            audit.setCreateTime(nowTime);
            audit.setSonUserName(name);
            audit.setIdentityCard(idCard);
            audit.setIdentityCardAddress(idAddress);
            audit.setPeriod(period);
            audit.setCityCode(cityCode);
            audit.setCityName(cityName);
            audit.setRelationType(Integer.parseInt(relationType));
            audit.setIdentifyPhotoFront(identifyPhotoFront);
            audit.setIdentifyPhotoReverse(identifyPhotoReverse);
            audit.setIdentifyPhotoHand(identifyPhotoHand);
            audit.setIdentifyPhotoHead(identifyPhotoHead);
            audit.setSignPicture(signPicture);
            audit.setSonUserPhone(phone);
            audit.setSourceType(Constant.SourceType.KAMENG);
            audit.setMerchantType(merchant.getMerchantType()); // 个人
            audit.setOrderStatus(3); // 待分配
            audit.setImgSource(Integer.parseInt(Constant.UPLOAD_IMG_CONFIG));
            audit.setDoGzt(Constant.DO_GZT); // 国政通开关：1做，2不做
            audit.setIsp("1");
            audit.setOpenModel("1");
            audit.setDetailType(1);
            boolean r = getUserDAO().addJobNumberAudit(user, audit);
			if (!r) {
                log.warn("addJobNumberAudit return false," + json);
				return StatusCode.SYSTEM_EXCEPTION.toJSON("系统忙，请稍后再试");
			}

            // 添加子工号需要加入redis自动审核(ams),因为无水印图存在服务器本地，所以需要从本地拿无水印图覆盖原来路径传给AMS(IOS老版本不需要做预审)
            audit.setIdentifyPhotoFront(identifyPhotoFront.replace("_narrow", ""));
            audit.setIdentifyPhotoReverse(identifyPhotoReverse.replace("_narrow", ""));
            audit.setIdentifyPhotoHand(identifyPhotoHand.replace("_narrow", ""));
            audit.setIdentifyPhotoHead(identifyPhotoHead.replace("_narrow", ""));
            final String auditStr = JSONObject.toJSONString(audit);
            Long result = userDAO.redis_rpush(RedisConstant.ADD_SON_JOB_NUM_AUDITED_KEY, auditStr);
            if (result == null) {
                log.error("redis连接异常");
                return StatusCode.SYSTEM_EXCEPTION.toJSON();
            }
            log.info("添加子工号预审： Redis(AMS) KEY:" + RedisConstant.ADD_SON_JOB_NUM_AUDITED_KEY + ",val:" + auditStr);

            return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		} finally {
			userDAO.redis_del(keyLock);
		}
	}

	protected String createSysOrderId() {
		return DateUtils.format(Clock.systemDefaultZone().millis(), "yyMMddHHmmss") + StringUtil.randomNumberString(6);
	}

	@Override
	public String getCode(JSONObject json) {
		try {
			if (!json.containsKey("phone") || json.getString("phone").length() != 11) {
				log.warn("param phone error");
				return StatusCode.PARAM_ERROR.toJSON("参数 开户号码 错误");
			}
			final String phone = json.getString("phone");
			User user = getUserDAO().getUserByPhone2(phone);
			String checkPhone = checkPhone(phone, user);
			if (checkPhone != null) {
				return checkPhone;
			}

			String key = RedisConstant.SELF_REGIS_CODE + phone;
			Long t = getUserDAO().redis_ttl(key);
			if (t == null || t < 20) {
				String code = StringUtil.randomNumberString(6);
				if (Constant.IS_TEST) {
					log.info("测试环境，验证码写死");
					code = "666666";
				}
				String content = "尊敬的用户,您手机的验证码为：" + code + "。";
				Boolean s = sendMsg(phone, content);
				if (!s) {
					log.warn("sendmsg return false");
					return StatusCode.SYSTEM_EXCEPTION.toJSON("验证码发送失败，请稍候再试");
				}
				getUserDAO().redis_set(key, code);
				getUserDAO().redis_expire(key, 120);
			}
			return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String createVisitor(JSONObject json) {
		try {
			if (!json.containsKey("phone") || json.getString("phone").length() != 11) {
				log.warn("param phone error");
				return StatusCode.PARAM_ERROR.toJSON("参数 开户号码 错误");
			}
			if (StringUtil.isNULL(json.getString("code"))) {
				log.warn("param code error");
				return StatusCode.PARAM_ERROR.toJSON("参数 验证码 错误");
			}
			// if(StringUtil.isNULL(json.getString("cityCode"))){
			// log.warn("param cityCode error");
			// return StatusCode.PARAM_ERROR.toJSON("参数 城市编码 错误");
			// }
			// if(StringUtil.isNULL(json.getString("cityName"))){
			// log.warn("param cityName error");
			// return StatusCode.PARAM_ERROR.toJSON("参数 城市 错误");
			// }
			String inviteCode = "";
			if (json.containsKey("inviteCode")) {
				inviteCode = json.getString("inviteCode");
			}
			final String phone = json.getString("phone");
			String key = RedisConstant.SELF_REGIS_CODE + phone;
			String coded = getUserDAO().redis_get(key);
			if (coded == null) {
				log.warn("code 失效");
				return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码已失效，请重新获取");
			}
			if (!coded.equals(json.getString("code"))) {
				log.warn("code error");
				return StatusCode.CAPTCHE_NOT_FOUND.toJSON("验证码错误");
			}
			User user = getUserDAO().getUserByPhone2(phone);
			String checkPhone = checkPhone(phone, user);
			if (checkPhone != null) {
				return checkPhone;
			}
			Merchant supMerchant = getUserDAO().getDealerInfoByInviteCode(inviteCode);
			String supDealerId = null;
			String supDealerName = null;
			if (null != supMerchant) {
				supDealerId = supMerchant.getDealerId();
				supDealerName = supMerchant.getCompanyName();
			}
			final long time = Clock.systemDefaultZone().millis();
			String userId = getUserId();
			String randname = "游客号" + StringUtil.randomNumberString(7);
			String merchantId = "YT" + DateUtils.format(time, "yyMMddHHmmss") + StringUtil.randomNumberString(6);
			SelfRegistering s = new SelfRegistering();
			s.setMerchantId(merchantId);
			s.setSuper_dealer_id(supDealerId);
			s.setSuper_dealer_name(supDealerName);
			s.setSupper_invite_code(inviteCode);
			s.setCreateTime(time);
			s.setUser_id(userId);
			s.setDealer_id(userId);
			s.setPhone(phone);
			s.setUser_name(randname);
			s.setCompany_name(randname);
			// s.setCityCode(json.getString("cityCode"));
			// s.setCityName(json.getString("cityName"));
			s.setCityCode("100");
			s.setCityName("全国");
			s.setRegistType(2);// 默认为有设备
			s.setOsversion(json.getString("osVersion"));
			s.setAppversion(json.getString("appVersion"));
			s.setOstype(json.getString("osType"));
			s.setPhonetype(json.getString("phoneType"));
			s.setNet(json.getString("net"));
			s.setApplicationID(json.getString("applicationID"));
			s.setHost_ip(json.getString("host_ip"));
			s.setLatitude(json.getString("latitude"));
			s.setLongitude(json.getString("longitude"));
			boolean r = getUserDAO().setVisitor(s);
			if (!r) {
				log.warn("创建游客账户错误，info:" + s.toString());
				return StatusCode.SYSTEM_EXCEPTION.toJSON("创建帐号失败，请重新再试。");
			}
			// 发送欢迎消息
			addWelcomeMsg(userId, s.getIs_main(), 1);
			JSONObject re = new JSONObject();
			re.put("tmsi", String.valueOf(s.getCreateTime()));
			re.put("cityCode", "100");
			re.put("cityName", "全国");
			re.put("inviteCode", inviteCode);
			re.put("sign", "2");
			re.put("leftFee", "0");
			re.put("userId", userId);
			return StatusCode.SUCCESS.toDiyJson("data", re);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	private String checkPhone(String phone, User user) {
        if (Objects.isNull(user)) {
			log.error("DB连接异常");
			return StatusCode.SYSTEM_EXCEPTION.toJSON("网络异常");
		}
		if (Objects.isNull(user.getUserId())) {
			return null;
		}

		int sourceType = user.getSourceType();
		if (1 == sourceType) {
			log.warn(phone + " be used");
			return StatusCode.USERNAME_EXISTED.toJSON("该手机号码已经是商户啦，请更换手机号码");
		}
		if (2 == sourceType) {
			log.warn(phone + " be used");
			return StatusCode.USERNAME_EXISTED.toJSON("该手机号码不能用于卡盟注册，请更换手机号码");
		}
		return null;
	}

    private String checkPhoneByState(String phone) {
        List<JobNumberAuditModel> jobNumberAuditList = userDAO.getJobNumberAuditList(phone, 2);
        if (Objects.nonNull(jobNumberAuditList) && jobNumberAuditList.size() > 0) {
            log.warn(phone + " be used");
            return StatusCode.USERNAME_EXISTED.toJSON("该手机号码正在子工号审核中，请更换手机号码");
        }
        return null;
    }

	private String checkIdCard(String idCard, int detailType) {
		if (ObjectUtils.isNullOrEmpty(idCard)) {
			return null;
		}
		User user = userDAO.getUserByIdCard(idCard, detailType);
		if (user != null) {
			log.info(idCard + "证件号已有用户，" + user.getUserId());
			return StatusCode.USERNAME_EXISTED.json().msg("该证件号正在被工号使用中，请更换证件").toString();
		}
		return null;
	}

    private String checkIdCardIsMain(String idCard, int detailType) {
        if (ObjectUtils.isNullOrEmpty(idCard)) {
            return null;
        }
        User user = userDAO.getUserByIdCardIsMain(idCard, detailType, 0);
        if (Objects.nonNull(user)) {
            log.info(idCard + "证件号已有用户，" + user.getUserId());
            return StatusCode.USERNAME_EXISTED.json().msg("该证件号正在被工号使用中，请更换证件").toString();
        }
        return null;
    }

    private String checkIdCardForAudit(String idCard) {
        if (ObjectUtils.isNullOrEmpty(idCard)) {
            return null;
        }
        JobNumberAudit audit = userDAO.getJobNumAuditByIdCard(idCard);
        if (Objects.nonNull(audit)) {
            log.info(idCard + "证件号正在审核中，" + audit.getOrderId());
            return StatusCode.USERNAME_EXISTED.json().msg("该证件号正在审核中，请更换证件").toString();
        }
        return null;
    }

	@Override
	public String uploadImg(User user, JSONObject json) {
		try {
            String imgSource = json.getString("imgSource");
			final String phone = user.getPhone();
			final int imgNo = json.getIntValue("imgNo");
			final String imgBase64 = json.getString("img");
            String uploadType = json.getString("uploadType");// 操作类型：3添加子工号
			log.info("userId=" + user.getUserId() + ",imgNo=" + imgNo);
			// 新增加mac、deviceId 便于图片合并,设备id写入图片
			// final String mac = json.getString("mac");
			final String deviceId = (json.getString("deviceId") != null) ? json.getString("deviceId") : "";
			if (imgBase64 == null) {
				log.warn("param img error");
				return StatusCode.PARAM_ERROR.toJSON("参数照片错误");
			}
            if (StringUtils.isNotBlank(imgSource) && StringUtils.isNotBlank(uploadType) && "3".equals(uploadType) && !Constant.UPLOAD_IMG_CONFIG.equals("3")) {
                if (!imgSource.equals(Constant.UPLOAD_IMG_CONFIG)) {
                    log.info("上传图片方式不正确，允许上传图片方式配置为：" + Constant.UPLOAD_IMG_CONFIG);
                    return StatusCode.PARAM_ERROR.toJSON("上传图片方式不正确，请选择正确方式上传。");
                }
            }

			final String YYYYMMdd = DateUtils.format("YYYYMMdd");
			final String YYMMddHHmmssSSS = DateUtils.format("YYMMddHHmmssSSS");
			// final String YYYYMM = DateUtils.format("YYYYMM");
			String imgName;
			String specialTag = "registing";
			final String subDir = YYYYMMdd + "/" + phone;
			switch (imgNo) {
			case 1:// 正面
				imgName = phone + "registone" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 2:// 背面
				imgName = phone + "registtwo" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 3:// 手持
				imgName = phone + "registthree" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 4:// 签名
				specialTag = "sign";
				// subDir = YYYYMMdd;
				imgName = phone + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 5:// 识别的小头像
				imgName = phone + "registfive" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 6:// 商户门头照片
				specialTag = "replenish";
				imgName = phone + "replenishOut" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 7:// 商户店内
				specialTag = "replenish";
				imgName = phone + "replenishIn" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 8:// 商户与门店合影
				specialTag = "replenish";
				imgName = phone + "replenish" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 9:// 企业商户资料补充身份证正面
				specialTag = "merchantPerfection";
				imgName = phone + "identityCardFront" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 10:// 企业商户资料补充身份证背面
				specialTag = "merchantPerfection";
				imgName = phone + "identityCardRear" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 11:// 企业商户资料补充身份证手持照片
				specialTag = "merchantPerfection";
				imgName = phone + "identityCardHand" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 12:// 企业商户营业执照
				specialTag = "replenish";
				imgName = phone + "businessLicense" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 13:// 商户完善身份证头像
				specialTag = "merchantPerfection";
				imgName = phone + "identityCardHead" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			case 14:// 商户完善活体识别照片
				specialTag = "merchantPerfection";
				imgName = phone + "LivingIdentify" + "_" + YYMMddHHmmssSSS + ".png";
				break;
			default:
				log.warn("param imgNo error,imgNo:" + imgNo);
				return StatusCode.PARAM_ERROR.toJSON("参数照片编号错误");
			}
			FileInfo fileInfo = FileInfo.newInstance(specialTag, subDir, imgName);
			final String parentPath = fileInfo.getParentPath();
			boolean ok = ImageUtils.writeImg(parentPath, imgName, imgBase64);
			if (!ok) {
				return StatusCode.SYSTEM_EXCEPTION.toJSON("上传图片失败，请稍后重试");
			}
            UploadResult uploadYuanTu = AliOSSUtil.upload(fileInfo.getParentPath() + imgName,fileInfo.getRelateDir()+imgName);
            if (!uploadYuanTu.isFlag()) {
                log.info("原图上传oss失败，图片路径：" + fileInfo.getParentPath() + imgName);
                return StatusCode.SYSTEM_EXCEPTION.toJSON("原图上传oss失败，请稍后重试");
            }
			final String imgNewName = imgName.substring(0, imgName.length() - 4) + "_narrow.png";
			final String newRelatePath = fileInfo.getRelateDir() + imgNewName;
            // 上传原图到OSS
            UploadResult result = AliOSSUtil.upload(fileInfo.getParentPath() + imgName, newRelatePath);
            log.info("原图上传到oss,路径:" + fileInfo.getParentPath() + imgNewName + "," + newRelatePath + "," + result);
            if (!result.isFlag()) {
                log.info("原图上传到oss失败,图片路径：" + fileInfo.getParentPath() + imgNewName);
                return StatusCode.SYSTEM_EXCEPTION.toJSON("图片上传oss失败，请稍后重试");
            }
            // 添加水印
			saveImgProcess(parentPath, imgName, imgNewName, phone, Color.white);
			// 图片存储到oss不清除本地图片，待自动审核结束后删除
			UploadResult upload = AliOSSUtil.upload(fileInfo.getParentPath() + imgNewName, newRelatePath);
			log.info("图片上传oss,路径:" + fileInfo.getParentPath() + imgNewName + "," + newRelatePath + "," + upload);
			if (!upload.isFlag()) {
				log.info("图片上传oss失败，图片路径：" + fileInfo.getParentPath() + imgNewName);
				return StatusCode.SYSTEM_EXCEPTION.toJSON("图片上传oss失败，请稍后重试");
			}
			if (imgNo == 4 || imgNo == 12 || imgNo == 13 || imgNo == 14) {// 兼容:商户实名补录手签名、个人和企业商户资料补充不校验设备信息
				int merchantType;
				if (deviceId.length() > 0) {
					DeviceIdInfo deviceInfo = getUserDAO().getDeviceIdInfo(deviceId);
					if (deviceInfo == null) {
						return StatusCode.ANNO_NOT_FOUND.toJSON("未查到设备相关信息，请更换其他设备。");
					}
					merchantType = deviceInfo.getAttribute();
				} else {
					// Merchant merchant =
					// merchantDAO.getByMerchantId(user.getMerchantId());
					merchantType = 1;// 商户实名补录手签名不校验设备信息
				}
				final String filePathName = fileInfo.getFilePath();
				final String signMergePicture = phone + "_" + YYMMddHHmmssSSS + "_merge.png";
				log.info(String.format("deviceId：%s，merchantType：%s", deviceId, merchantType));
				saveImgNarrow(filePathName, fileInfo.getParentPath(), phone, deviceId, signMergePicture, merchantType);
				String signMergeRelate = fileInfo.getRelateDir() + signMergePicture;
				UploadResult upload1 = AliOSSUtil.upload(fileInfo.getParentPath() + signMergePicture,
						signMergeRelate.substring(1));
				if (!upload1.isFlag()) {
					log.info("图片上传oss失败，图片路径：" + fileInfo.getParentPath() + signMergePicture);
					return StatusCode.SYSTEM_EXCEPTION.toJSON("图片上传oss失败，请稍后重试");
				}
				// return
				// StatusCode.SUCCESS.toDiyJson(true,"data","{\"imgName\":\""+
				// path + signMergePicture+"\"}");
			}

			// final String netUrl = Constant.ums_url+path +
			// imgName.substring(0,imgName.length()-4)+"_narrow.png";
			// return
			// StatusCode.SUCCESS.toDiyJson(true,"data","{\"imgName\":\""+
			// netUrl +"\"}");
			return StatusCode.SUCCESS.toDiyJson(true, "data", "{\"imgName\":\"" + newRelatePath + "\"}");
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String selfRegistering(User user, JSONObject json) {
		final String lockKey = "selfregist" + user.getUserId();
		boolean lock = userDAO.redis_setNx(lockKey, "1");
		if (!lock) {
			return StatusCode.PARAM_ERROR.json().msg("请求过快").toString();
		}
		try {
			// 版本信息
			// final String boryaAuthStr = json.getString("boryaAuth");
			// final int backgroundVersion =
			// json.getIntValue("backgroundVersion");
			// HeaderEntity authHeader = JSONObject.parseObject(boryaAuthStr,
			// HeaderEntity.class);
			// SystemConfig instance = SystemConfig.getInstance();

			userDAO.redis_expire(lockKey, 600);
            final String idCard = String.valueOf(json.getString("idCard")).trim(); // 个人：身份证号码，企业：营业执照编号
			String storeAddressBase = json.getString("storeAddress");// 门店地址
			final String storeAddress = storeAddressBase == null ? "" : storeAddressBase.replaceAll("\r|\n", "");
			final String period = json.getString("period");
			final String alipayId = json.getString("alipayId");
			final String weichatId = json.getString("weichatId");
            String identityCard = json.getString("identityCard"); // 企业和个人都是身份证号码
			String identityCardName = json.getString("identityCardName");
			String identityCardAddress = json.getString("identityCardAddress");
			String identifyPhotoHead = json.getString("identifyPhotoHead");
			String identifyPhotoFront = json.getString("identifyPhotoFront");
			String identifyPhotoReverse = json.getString("identifyPhotoReverse");
			String identifyPhotoHand = json.getString("identifyPhotoHand");
			String merchantType = json.getString("merchantType");
			String shopAddress = json.getString("shopAddress");
			String shopSpecificAddress = json.getString("shopSpecificAddress");

			// 暂时不需要校验身份证信息唯一性
			// if (authHeader.getAppVersion() >= backgroundVersion) {
			// Merchant merchant =
			// getUserDAO().getByDetailTypeAndIdentityCard(user.getDetailType(),
			// identityCard, null);
			// if (Objects.nonNull(merchant)) {
			// log.warn("该商户身份证信息已存在,detailType is" + user.getDetailType());
			// return StatusCode.SYSTEM_EXCEPTION.toJSON("该商户身份证信息已存在");
			// }
			// }

            if (StringUtils.isBlank(merchantType)) {
                log.warn("param merchantType is empty");
                return StatusCode.PARAM_ERROR.toJSON("merchantType不能为空");
            }

            // 校验身份证号码、企业营业执照已激活用户数量
            String checkIdCardAndBusinessLicence = checkIdCardAndBusinessLicence(merchantType, identityCard, user, idCard);
            if (StringUtils.isNotBlank(checkIdCardAndBusinessLicence)) {
                return checkIdCardAndBusinessLicence;
            }

			String checkIdCardBlack = checkIdCardIsBlack(idCard);
			if (checkIdCardBlack != null) {
				return checkIdCardBlack;
			}
			if (user.getSourceType() == 1 && StringUtil.isNULL(alipayId) && StringUtil.isNULL(weichatId)) {
				log.warn("param alipayId weichatId empty");
				return StatusCode.PARAM_ERROR.toJSON("微信或支付宝必须填写一个");
			}
			SelfRegistering s = getUserDAO().getVisitorInfo(user.getDealerId());
			if (ObjectUtils.isNull(s)) {
				log.warn("getVisitorInfo return null");
				return StatusCode.SYSTEM_EXCEPTION.toJSON("用户不存在");
			}
			switch (s.getStatus()) {
			case 0:
				log.warn("非游客激活," + s.toString());
				return StatusCode.SYSTEM_EXCEPTION.toJSON("你已激活，可以进行开卡操作。");
			case 3:
				log.warn("激活审核中," + s.toString());
				return StatusCode.SYSTEM_EXCEPTION.toJSON("您的激活申请正在审核中，请不要重复提交。");
			default:
				break;
			}
			// 喜牛商户校验电子合同填写商户信息
			if (user.getSourceType() == SourceType.XINIU && user.getDetailType() == Constant.DetailType.XINIU) {
				Map<String, String> allTables = appConfDAO.getAllTables(user.getDetailType());
				Map<String, String> merchInfo = getUserDAO().getBuyModelInfo(user.getMerchantId(), allTables);
				// sign_pic_url,merch_type,merch_name,call_name,buz_code
				String sign_pic_url = merchInfo.get("sign_pic_url");
				String merch_type = merchInfo.get("merch_type");
				String merch_name = merchInfo.get("merch_name");
				// String call_name = merchInfo.get("call_name");
				String buz_code = merchInfo.get("buz_code");

				String userName = json.getString("userName").replaceAll("\r|\n", "");
				String companyName = StringUtils.isBlank(json.getString("companyName")) ? userName
						: json.getString("companyName").replaceAll("\r|\n", "");
				// String idCard = json.getString("idCard");
				if (!"0".equals(merch_type) && !merchantType.equals(merch_type)) {
					log.warn(user.getUserId() + "商户属性和购买时不同；原信息：" + merch_type + ",激活提交信息：" + merchantType
							+ ",sign_pic_url=" + sign_pic_url);
					return StatusCode.SYSTEM_EXCEPTION.toJSON("商户属性和购买时不同。");
				}
				// 根据需求喜牛请求时不校验商户联系人
				// if ("1".equals(merchantType)) {
				// if (!StringUtil.isNULL(call_name) &&
				// !userName.equals(call_name)) {
				// log.warn(user.getUserId() + "商户联系人和购买时不同；原信息：" + call_name +
				// ",激活提交信息：" + userName);
				// return StatusCode.SYSTEM_EXCEPTION.toJSON("商户联系人和购买时不同。");
				// }
				// }
				if (!StringUtil.isNULL(merch_name) && !companyName.equals(merch_name)) {
					log.warn(user.getUserId() + "商户名称和购买时不同；原信息：" + merch_name + ",激活提交信息：" + companyName);
					return StatusCode.SYSTEM_EXCEPTION.toJSON("商户名称和购买时不同。");
				}
				if (!StringUtil.isNULL(buz_code) && !idCard.equalsIgnoreCase(buz_code)) {
					log.warn(user.getUserId() + "商户证件编号和购买时不同；原信息：" + buz_code + ",激活提交信息：" + idCard);
					return StatusCode.SYSTEM_EXCEPTION.toJSON("商户证件编号和购买时不同。");
				}

			}
			final String kMRecordCode = json.getString("deviceCode");
			String devMacAddress = "";
			if (json.containsKey("devMac")) {
				devMacAddress = json.getString("devMac");
			}
			// 用户填写的设备Id
			DeviceIdInfo deviceInfo = getUserDAO().getDeviceIdInfo(kMRecordCode);
			String checkDevice = checkDevice(deviceInfo, kMRecordCode, user);
			if (ObjectUtils.nonNull(checkDevice)) {
				return checkDevice;
			}
			if (!devMacAddress.equals(deviceInfo.getMac())) {
				log.warn("mac地址不一致，request macaddress:" + devMacAddress + ",info:" + deviceInfo.toString());
			}
			s.setKMRecordCode(kMRecordCode);
			s.setPopchannel(deviceInfo.getSuper_dealerid());
			s.setPopchannel_name(deviceInfo.getDealer_name());
			s.setDevMacAddress(deviceInfo.getMac());
			// 1.0:
			// ib_kameng_deliveryrecord中attribute和merchante_attribute定义一致ABCD
			final int isp = deviceInfo.getIsp();
			s.setMerchant_attribute(isp);
			// 新增isp,provinceName绑定设备所属售卡权限及范围
			// isp,provinceNamec查询到一个scopeId插入商户激活审核表
			final String subStr = deviceInfo.getProvinceName().trim().substring(0, 2);// 取省份名称前两位模糊匹配区域码
			Scope checkScope = getWebUserDAO().checkScope(isp, subStr);
			if (StringUtil.isNULL(checkScope)) {
				log.warn("submitInfo[参数isp：provinceName错误]" + isp + ":" + deviceInfo.getProvinceName());
				return StatusCode.PARAM_ERROR.toJSON("营运商和区域对应位置编号不存在");
			}
			s.setScopeId(checkScope.getScopeId());
			/********************** Model继承17-10-26 ***************************/
			ModelInfo modelInfo = getUserDAO().getDealerModel(deviceInfo.getSuper_dealerid());
			if (ObjectUtils.isNull(modelInfo)) {
				log.warn("getDealerModel return null," + deviceInfo);
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			s.setPhoneModel(modelInfo.getPhoneModel());
			s.setDiscountModel(modelInfo.getDiscountModel());
			s.setTransterModel(modelInfo.getIncomeTransterModel());
			s.setPackModel(modelInfo.getPackModel());
			s.setDwkModel(modelInfo.getDwkModel());
			s.setWhiteCardPay(modelInfo.getWhiteCardPay());
			s.setWhiteCardReturn(modelInfo.getWhiteCardReturn());
			/********************** Model继承17-10-26 ***************************/
			if (StringUtils.isBlank(s.getSuper_dealer_id())) {
				final String inviteCode = json.getString("inviteCode");// 邀请码
				Merchant supMerchant = getUserDAO().getDealerInfoByInviteCode(inviteCode);
				String supDealerId = "";
				String supDealerName = "";
				if (Objects.nonNull(supMerchant)) {
					// 是卡盟的商户,邀请码不是卡盟的就提示错误信息
					if (user.getSourceType() == SourceType.KAMENG && supMerchant.getSourceType() != SourceType.KAMENG) {
						log.warn("非卡盟邀请码,userId=" + user.getUserId() + ",inviteCode=" + inviteCode);
						return StatusCode.PARAM_ERROR.toJSON("邀请码填写错误,请重新输入");
					}

					supDealerId = supMerchant.getDealerId();
					supDealerName = supMerchant.getCompanyName();
				}
				s.setSuper_dealer_id(supDealerId);
				s.setSuper_dealer_name(supDealerName);
				s.setSupper_invite_code(inviteCode);
			}

			final String imgNo1 = json.getString("imgNo1");
			final String imgNo2 = json.getString("imgNo2");
			final String imgNo3 = json.getString("imgNo3");
			final String imgNo5 = json.getString("imgNo5");
			if (!checkImg(Constant.IMG_SAVE_PATH + imgNo1)) {
				return StatusCode.PARAM_ERROR.toJSON("证件照1不存在");
			}
			if (!checkImg(Constant.IMG_SAVE_PATH + imgNo2)) {
				return StatusCode.PARAM_ERROR.toJSON("证件照2不存在");
			}
			if (!checkImg(Constant.IMG_SAVE_PATH + imgNo3)) {
				return StatusCode.PARAM_ERROR.toJSON("手持照片不存在");
			}
			if (StringUtils.isNotBlank(imgNo5) && !checkImg(Constant.IMG_SAVE_PATH + imgNo5)) {
				return StatusCode.PARAM_ERROR.toJSON("身份证头像不存在");
			}

			final String imgNo4_ = json.getString("imgNo4");
			final String imgNo4 = Constant.IMG_SAVE_PATH + imgNo4_;
			if (!checkImg(imgNo4))
				return StatusCode.PARAM_ERROR.toJSON("签名照片不存在");
			// 签名合并的图片 使用原图片合并 去掉水印标识
			final String signMergePicture = (imgNo4_.substring(0, imgNo4_.lastIndexOf(".")) + "_merge.png")
					.replace("_narrow", "");
			final long nowTime = Clock.systemDefaultZone().millis();
			final String orderId = "RE" + DateUtils.format(nowTime, "yyMMddHHmmss") + user.getPhone().substring(4);
			s.setOrderId(orderId);
			s.setModifyTime(nowTime);
			s.setMerchantType(json.getIntValue("merchantType"));
			final String userName = json.getString("userName").replaceAll("\r", "").replaceAll("\n", "");
			s.setUser_name(userName);
			s.setCompany_name(StringUtils.isBlank(json.getString("companyName")) ? userName
					: json.getString("companyName").replaceAll("\r", "").replaceAll("\n", ""));
			s.setIdCard(json.getString("idCard"));
			s.setCityCode(json.getString("cityCode"));
			s.setCityName(json.getString("cityName"));
			String address = json.getString("address").replaceAll("\r", "").replaceAll("\n", "");
			s.setAddress(address);
			s.setImgNo1(json.getString("imgNo1"));
			s.setImgNo2(json.getString("imgNo2"));
			s.setImgNo3(json.getString("imgNo3"));
			s.setImgNo4(json.getString("imgNo4"));
			s.setUser_id(user.getUserId());
			s.setAlipay_user_id(alipayId);
			s.setWeixin_user_id(weichatId);
			s.setPhone(user.getPhone());
			s.setSignMergePicture(signMergePicture);
			s.setDealer_id(user.getDealerId());
			s.setPeriod(period);
			s.setHeadPicture(imgNo5);
			if (1 == json.getIntValue("merchantType")) {
				s.setStoreAddress(StringUtils.isBlank(storeAddress) ? address : storeAddress);
			} else {
				s.setStoreAddress(storeAddress);
			}
			if (ObjectUtils.nonNullOrEmpty(s.getSuper_dealer_id())) {
				Merchant supSupMem = getUserDAO().getMerchant(s.getSuper_dealer_id());
				if (ObjectUtils.nonNull(supSupMem)) {
					s.setSuperSuperDealerId(supSupMem.getSuperDealerId());
					s.setSuperSuperDealerName(supSupMem.getSuperDealerName());
				}
			}
			s.setIsManage(deviceInfo.getIsManager());
			s.setSourceType(user.getSourceType());
			s.setDetailType(user.getDetailType());
			if (StringUtils.isNotBlank(shopAddress)) {
				s.setShopAddress(shopAddress);
			}
			if (StringUtils.isNotBlank(shopSpecificAddress)) {
				s.setShopSpecificAddress(shopSpecificAddress);
			}
			if ("1".equals(merchantType)) {
				if (StringUtils.isNotBlank(identityCard)) {
					s.setIdentityCard(identityCard);
				}
				if (StringUtils.isNotBlank(identityCardName)) {
					s.setIdentityCardName(identityCardName);
				}
				if (StringUtils.isNotBlank(identityCardAddress)) {
					s.setIdentityCardAddress(identityCardAddress);
				}
				if (StringUtils.isNotBlank(identifyPhotoHead)) {
					s.setIdentifyPhotoHead(identifyPhotoHead);
				}
				if (StringUtils.isNotBlank(identifyPhotoFront)) {
					s.setIdentifyPhotoFront(identifyPhotoFront);
				}
				if (StringUtils.isNotBlank(identifyPhotoReverse)) {
					s.setIdentifyPhotoReverse(identifyPhotoReverse);
				}
				if (StringUtils.isNotBlank(identifyPhotoHand)) {
					s.setIdentifyPhotoHand(identifyPhotoHand);
				}
			} else {
				if (StringUtils.isNotBlank(json.getString("idCard"))) {
					s.setIdentityCard(json.getString("idCard"));
				}
				if (StringUtils.isNotBlank(userName)) {
					s.setIdentityCardName(userName);
				}
				if (StringUtils.isNotBlank(address)) {
					s.setIdentityCardAddress(address);
				}
				if (StringUtils.isNotBlank(imgNo5)) {
					s.setIdentifyPhotoHead(imgNo5);
				}
				if (StringUtils.isNotBlank(imgNo1)) {
					s.setIdentifyPhotoFront(imgNo1);
				}
				if (StringUtils.isNotBlank(imgNo2)) {
					s.setIdentifyPhotoReverse(imgNo2);
				}
				if (StringUtils.isNotBlank(imgNo3)) {
					s.setIdentifyPhotoHand(imgNo3);
				}
			}
			boolean r = getUserDAO().addRegistMerchant(s);
			if (!r) {
				log.warn("addRegistMerchant return " + r);
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			RespInfo respInfo;
			String orderType = "";
			// if (authHeader.getAppVersion() >= backgroundVersion) {
			if (StringUtils.isNotBlank(identityCard)) { // 不为空代表为新版本
				// 校验是否有签署过隐私协议
				MerchantDetailInfo info = userDAO.getMerchantDetail(user.getMerchantId());
				if (Objects.isNull(info)) {
					// 保存隐私协议签署记录
					boolean bool = userDAO.addMerchantDetail(user.getMerchantId());
					if (!bool) {
						log.warn("addMerchantDetail return " + bool);
						return StatusCode.SYSTEM_EXCEPTION.toJSON();
					}
				}
				orderType = "1";
			}

			if ("1".equals(merchantType)) {
				identityCard = StringUtils.isNotBlank(identityCard) ? identityCard : s.getIdCard();
				identityCardName = StringUtils.isNotBlank(identityCardName) ? identityCardName : s.getUser_name();
				identityCardAddress = StringUtils.isNotBlank(identityCardAddress) ? identityCardAddress
						: s.getAddress();
				identifyPhotoFront = StringUtils.isNotBlank(identifyPhotoFront) ? identifyPhotoFront : s.getImgNo1();
				identifyPhotoReverse = StringUtils.isNotBlank(identifyPhotoReverse) ? identifyPhotoReverse
						: s.getImgNo2();
				identifyPhotoHand = StringUtils.isNotBlank(identifyPhotoHand) ? identifyPhotoHand : s.getImgNo3();
				// 企业
				respInfo = new RespInfo(orderId, "1", merchantType, String.valueOf(s.getMerchant_attribute()), "1",
						identityCard, identityCardName, identityCardAddress, Constant.ums_url + identifyPhotoFront,
						Constant.ums_url + identifyPhotoReverse, Constant.ums_url + identifyPhotoHand);
				if (StringUtils.isNotBlank(period)) {
					respInfo.setIdCardPeriod(period);
				}
				if (StringUtils.isNotBlank(identifyPhotoHead)) {
					respInfo.setHeadImageLocation(Constant.ums_url + identifyPhotoHead);
				}
			} else {
				// 个人
				respInfo = new RespInfo(orderId, "1", json.getString("merchantType"),
						String.valueOf(s.getMerchant_attribute()), "1", s.getIdCard(), s.getUser_name(), s.getAddress(),
						Constant.ums_url + s.getImgNo1(), Constant.ums_url + s.getImgNo2(),
						Constant.ums_url + s.getImgNo3());
				if (StringUtils.isNotBlank(period)) {
					respInfo.setIdCardPeriod(period);
				}
				if (StringUtils.isNotBlank(s.getHeadPicture())) {
					respInfo.setHeadImageLocation(Constant.ums_url + s.getHeadPicture());
				}
			}
			if (StringUtils.isNotBlank(orderType)) {
				respInfo.setOrderType(orderType); // 走老流程
			}

			AutomaticAudittask.getInstance().execute(JSONObject.toJSONString(respInfo));
			if (s.getIsManage() == 1) {
				String msg = "审核结果将以业务消息的形式通知，请您注意查收!\r激活成功，您便可以对专营号段进行流转申请操作。";
				return StatusCode.SUCCESS.json().msg(msg).toString();
			}
			return StatusCode.SUCCESS.toJSON();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		} finally {
			userDAO.redis_del(lockKey);
		}
	}

	private Boolean checkImg(String dir) {
		File f = new File(dir);
		return f.exists();
	}

	@Override
	public String checkDeviceId(User user, JSONObject json) {
		try {
			final String deviceId = json.getString("deviceId");
			if (StringUtil.isNULL(deviceId)) {
				log.warn("param deviceId error");
				return StatusCode.SYSTEM_EXCEPTION.toJSON("参数 设备号 错误");
			}
			DeviceIdInfo d = getUserDAO().getDeviceIdInfo(deviceId);
			String checkDevice = checkDevice(d, deviceId, user);
			if (ObjectUtils.nonNull(checkDevice)) {
				return checkDevice;
			}
			Merchant mem = userDAO.getMerchant(user.getDealerId());
			String superInviteCode = "";
			String superMerchant = "";
			if (Objects.nonNull(mem)) {
				superInviteCode = mem.getSuperInviteCode();
				superMerchant = mem.getSuperDealerName();
			}
			String descStr = "";
			if (d.getIsManager() == 1) {
				descStr = "当前设备为专营号管理设备，激活成功后请到'发现——卡盟小站——专营号流转申请'中进行专营号段流转申请操作。";
			}
			StringBuilder sb = new StringBuilder();
			/** 由于不需要判断是否有上级商户，所以写死为1 **/
			sb.append("{\"superLived\":\"").append(1).append("\"");
			/** 由于不需要判断是否有上级商户，所以写死为1 **/
			sb.append(",\"channelName\":\"").append(d.getDealer_name()).append("\"");
			sb.append(",\"attribute\":\"").append(d.getIsp()).append("\"");
			// 2018-04-11 新增返回参数
			sb.append(",\"attributeStr\":\"").append(transMerchantIsp(d.getIsp(), d.getProvinceName())).append("\"");

			/** 新增返回上级邀请码 **/
			sb.append(",\"superInviteCode\":\"").append(superInviteCode).append("\"");
			sb.append(",\"superMerchantName\":\"").append(superMerchant).append("\"");

			sb.append(",\"descStr\":\"").append(descStr).append("\"");
			sb.append("}");
			return StatusCode.SUCCESS.toDiyJson("data", sb);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	private String transMerchantIsp(int isp, String province) {
		String str = "";
		switch (isp) {
		case 1:
			str = "远特售卡";
			break;
		case 2:
			str = "联通售卡";
			break;
		case 3:
			str = "移动售卡";
			break;
		case 4:
			str = "电信售卡";
			break;
		default:
			str = "未知";
			break;
		}

		return province + str;
	}

	@Override
	public String checkPowerForModel(User user, JSONObject json) {
		try {
			Integer c = getUserDAO().checkPowerForModel(user.getUserId());
			if (c == null) {
				return StatusCode.SYSTEM_EXCEPTION.toJSON();
			}
			JSONObject r = new JSONObject();
			if (!c.equals(1)) {
				r.put("price", "0");
				r.put("maxNums", "0");
				r.put("power", c.toString());
			} else {
				KamengModelConfig k = getUserDAO().getPrice();
				if (k == null) {
					return StatusCode.SYSTEM_EXCEPTION.toJSON();
				}
				r.put("price", String.valueOf(k.getPrice()));
				r.put("maxNums", String.valueOf(k.getMax_num()));
				r.put("power", c.toString());
			}

			return StatusCode.SUCCESS.toDiyJson("data", r);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	@Override
	public String bannerList(User user) {
		try {
			Merchant mem = getUserDAO().getMerchant(user.getDealerId());
			if (mem == null) {
				log.warn("getMerchant return null," + user.getDealerId());
				return StatusCode.USER_NOT_FOUND.toJSON();
			}
			JSONObject data = new JSONObject();
			JSONArray banners = new JSONArray();
			if (StringUtils.isBlank(mem.getBannerIds())) {
				List<BannerInfo> list = getUserDAO().getBannerList();
				if (list == null) {
					log.warn("getBannerList default return null");
				} else {
					for (int i = 0, size = list.size(); i < size; i++) {
						BannerInfo banner = list.get(i);
						JSONObject each = new JSONObject();
						each.put("imgUrl", banner.getBanner_url());
						each.put("linkUrl", banner.getLink_url());
						each.put("title", banner.getTitle());
						banners.add(each);
					}
				}
			} else {
				Map<String, BannerInfo> map = getUserDAO().getBannerList(mem.getBannerIds());
				if (map == null || map.isEmpty()) {
					log.warn("getBannerList return null,bannerIds:" + mem.getBannerIds());
					List<BannerInfo> list = getUserDAO().getBannerList();
					if (list == null) {
						log.warn("getBannerList default return null");
					} else {
						for (int i = 0, size = list.size(); i < size; i++) {
							BannerInfo banner = list.get(i);
							JSONObject each = new JSONObject();
							each.put("imgUrl", banner.getBanner_url());
							each.put("linkUrl", banner.getLink_url());
							each.put("title", banner.getTitle());
							banners.add(each);
						}
					}
				} else {
					List<String> list = Arrays.asList(mem.getBannerIds().split(","));
					for (String bannerId : list) {
						if (map.containsKey(bannerId)) {
							BannerInfo banner = map.get(bannerId);
							JSONObject each = new JSONObject();
							each.put("imgUrl", banner.getBanner_url());
							each.put("linkUrl", banner.getLink_url());
							each.put("title", banner.getTitle());
							banners.add(each);
						}
					}
				}
			}
			data.put("bannerNum", banners.size() + "");
			data.put("bannerList", banners);
			return StatusCode.SUCCESS.toDiyJson("data", data);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
	}

	private String checkDevice(DeviceIdInfo deviceInfo, String paramDeviceId, User user) {
		if (deviceInfo == null) {
			log.warn("Not found deviceinfo.deviceCode=" + paramDeviceId);
			return StatusCode.ANNO_NOT_FOUND.toJSON("未查到该设备相关信息，请更换其他设备。");
		}
		if (user.getSourceType() == Constant.SourceType.KAMENG) {
			List<String> appDealerIds = appConfDAO.getAll(OtherConfType.MODEL_DEALERIDS);
			if (appDealerIds == null) {
				log.warn("getModelDealerId return null," + null);
				return StatusCode.SYSTEM_EXCEPTION.json().toString();
			}
			if (ObjectUtils.nonNullOrEmpty(deviceInfo.getSuper_dealerid())
					&& appDealerIds.contains(deviceInfo.getSuper_dealerid())) {
				log.warn("喜牛的设备不能用于卡盟绑定," + deviceInfo.toString());
				return StatusCode.ANNO_NOT_FOUND.toJSON("该设备不能用于卡盟平台，请更换其他设备。");
			}
		} else {
			List<String> appDealerIds = appConfDAO.getConfValues(OtherConfType.MODEL_DEALERIDS, user.getDetailType());
			if (appDealerIds == null) {
				log.warn("getModelDealerId return null," + user.getDetailType());
				return StatusCode.SYSTEM_EXCEPTION.json().toString();
			}
			if (ObjectUtils.nonNullOrEmpty(deviceInfo.getSuper_dealerid())
					&& !appDealerIds.contains(deviceInfo.getSuper_dealerid())) {
				log.info("设备不对应," + deviceInfo.toString());
				return StatusCode.ANNO_NOT_FOUND.toJSON("该设备不能用于本平台，请更换其他设备。");
			}
			Merchant mem = userDAO.getMerchant(user.getDealerId());
			if (mem == null) {
				log.warn("商户信息未找到," + user.getUserId());
				return StatusCode.ANNO_NOT_FOUND.toJSON("用户信息有误，请稍后再试。");
			}
			if (mem.getYtskStatus() < 2) {
				AppTypeInfo appTypeInfo = appConfDAO.getAppInfo(user.getDetailType());
				log.warn("喜牛等级不足," + mem.getYtskStatus());
				return StatusCode.ANNO_NOT_FOUND.toJSON("您还是" + appTypeInfo.getMsgName() + "游客，请先购买设备。");
			}
		}

		if (deviceInfo.getIsManager() == 0) {
			if (deviceInfo.getState() == 1) {
				log.warn("设备已被占用,info:" + deviceInfo.toString());
				return StatusCode.SYSTEM_EXCEPTION.toJSON("该设备已被激活，请更换其他设备。");
			}
			if (deviceInfo.getState() == 2) {
				log.warn("设备已被占用,info:" + deviceInfo.toString());
				return StatusCode.SYSTEM_EXCEPTION.toJSON("该设备已被锁定，请更换设备。");
			}
		}
		return null;
	}

	/**
	 * 添加水印
	 *
	 * @param imgPath
	 * @param imgName
	 * @param imgNewName
	 * @return
	 */
	protected void saveImgProcess(String imgPath, String imgName, String imgNewName, String dealerId, Color color) {
		String waterText = "办理时间" + DateUtils.format("yyyy-MM-dd HH:mm:ss") + "渠道ID编号" + dealerId
				+ "仅用于远特通信或中国联通移动业务办理";
		// waterWordsByImg(waterText,
		// imgPath+"/"+imgName,imgPath+"/"+imgNewName);
		ImageUtils.waterWordsAuto(waterText, imgPath + "/" + imgName, imgPath + "/" + imgNewName, color);
	}

	public String addProtocolData(User user) {
		String merchantId = user.getMerchantId();
		MerchantDetailInfo info = userDAO.getMerchantDetail(merchantId);
		UserClientDetail userClient = merchantDAO.getUserClientByUserId(user.getUserId());
		boolean result = Objects.isNull(info); // 为空代表没有签署过
		// 1主账号0 子账号
		if (0 == userClient.getIsMain() && result) {
			log.warn("该用户主工号没有签署协议,userId:" + user.getUserId());
			return StatusCode.SYSTEM_EXCEPTION.toJSON("请联系主工号进行隐私协议签署，子工号不允许签署。");
		}
		boolean bool;
		if (result) {
			bool = userDAO.addMerchantDetail(merchantId);
		} else {
			bool = userDAO.updateMerchantDetail(merchantId);
		}
		if (!bool) {
			log.error("数据库异常");
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}

		return StatusCode.SUCCESS.toJSON();
	}

	public String getProtocolData(User user) {
		JSONObject data = new JSONObject();
		String merchantId = user.getMerchantId();
		Merchant merchant = merchantDAO.getByMerchantId(merchantId);
		if (Objects.isNull(merchant)) {
			log.error("DB 连接异常，merchantId:" + merchantId);
			return StatusCode.SYSTEM_EXCEPTION.toJSON();
		}
		// 是游客
		if (0L == merchant.getRegistTime() || 0L > merchant.getRegistTime()) {
			data.put("result", "3"); // 是否签订过协议，1是，2否，3游客
		} else {
			MerchantDetailInfo info = userDAO.getMerchantDetail(merchantId);
			boolean result = Objects.isNull(info); // 为空代表没有签署过
			data.put("result", result ? "2" : "1"); // 是否签订过协议，1是，2否
		}

		return StatusCode.SUCCESS.toDiyJson("data", data);
	}

    @Override
    public String getRelationTypeList(JSONObject json) {
        List<RelationModel> modelList = getUserDAO().getRelationTypeList();
        if (Objects.isNull(modelList)) {
            log.error("DB connection exception");
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }

        JSONObject jsonObject = new JSONObject();
        jsonObject.put("list", modelList);

        return StatusCode.SUCCESS.toDiyJson("data", jsonObject);
    }

    @Override
    public String getSonJobNumProtocol(User user, JSONObject json) {
        String userId = json.getString("staffUserId");
        if (StringUtils.isBlank(userId)) {
            userId = user.getUserId();
        }
        SonJobNumProtocolModel model = userDAO.getSonJobNumProtocol(userId);
        if (Objects.isNull(model)) {
            log.error("DB:getSonJobNumProtocol is null,userId=" + userId);
            return StatusCode.SYSTEM_EXCEPTION.toJSON();
        }
        Merchant merchant = userDAO.getMerchantById(user.getMerchantId());
        if (Objects.nonNull(merchant)) {
            model.setMainUserName(merchant.getCompanyName());
        }

        return StatusCode.SUCCESS.toDiyJson(true, "data", JSONObject.toJSONString(model));
    }

	// /**
	// * 水印文字,图片输出采用JPEGImageEncoder比ImageIO.write 生成的图片文件小
	// * @param waterText
	// * @param srcImgPath
	// * @param targerPath
	// * @throws Exception
	// */
	// private boolean waterWordsByImg(String waterText, String srcImgPath,
	// String targerPath) {
	// OutputStream os = null;
	// try {
	// Image srcImg = ImageIO.read(new File(srcImgPath));
	// final int srcHeight = srcImg.getHeight(null);
	// final int srcWidth = srcImg.getWidth(null);
	// //TYPE_BYTE_INDEXED TYPE_USHORT_555_RGB TYPE_USHORT_565_RGB
	// BufferedImage buffImg = new BufferedImage(srcWidth,srcHeight,
	// BufferedImage.TYPE_INT_RGB);
	//
	// // 1、得到画笔对象
	// Graphics2D g = buffImg.createGraphics();
	//
	// g.drawImage(srcImg, 0, 0, srcWidth, srcHeight, null);
	// int big = 22;
	// if(srcHeight > 1500){
	// big = 34;
	// }
	// // 3、设置水印旋转
	// g.setFont( new Font("宋体", Font.PLAIN, big));
	// g.setColor(Color.WHITE);
	// // 旋转文本
	//// int y = srcHeight / 2 * 1;
	//// int i = 0;
	////
	//// g.rotate(-30 * Math.PI / 180,i * 2,i * 200 + y);
	//// g.drawString(waterText,i * 2,i * 200 + y);
	////
	//// for (int x=0; x < srcWidth/5 * 3+50; x+=40) {
	//// i ++;
	//// g.drawString(waterText,i *2, i * 100 + y);
	//// }
	// //=========================================================
	//// int y = srcHeight;
	//// g.rotate((Math.toDegrees(Math.atan(Double.valueOf(srcWidth)/y))-88) *
	// Math.PI / 180,20,y-25);
	//// g.drawString(waterText,20, y-25);
	//
	// g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.8f));
	// g.rotate((Math.toDegrees(Math.atan(Double.valueOf(srcWidth)/srcHeight))-88)
	// * Math.PI / 180,srcWidth/6,srcHeight/6*5);
	// g.drawString(waterText,srcWidth/6, srcHeight/6*5);
	//
	//
	// // 7、释放资源
	// g.dispose();
	//
	// // 8、生成图片
	// os = new FileOutputStream(targerPath);
	//
	// JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
	// encoder.encode(buffImg); //近JPEG编码
	// os.close();
	//
	// return true;
	// } catch (Exception e) {
	// e.printStackTrace();
	// return false;
	// } finally {
	// try {
	// if (null != os)
	// os.close();
	// } catch (Exception e) {
	// log.error(e.getMessage(),e);
	// }
	// }
	// }

	// public static void main(String[] args) {
	// String water =
	// "办理时间"+DateUtils.format(Clock.systemDefaultZone().millis(),"yyyy-MM-dd
	// HH:mm:ss")+
	// "渠道ID编号"+"dealerId"+",仅用于远特通信或中国联通移动业务办理";
	// waterWordsAuto(water,"D://aaa/test/testums.jpg","D://aaa/test/testums1.jpg",Color.white);
	// }
}